package pl.edu.mimuw.irs.core.model.simulation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import pl.edu.mimuw.irs.core.model.analysis.History;

public class Calculations {

	// *** Attributes

	private List<History> runs;
	private int minCost;
	private int maxCost;
	private int avgCost;
	private int lquCost;
	private int medCost;
	private int hquCost;
	private int minTime;
	private int maxTime;
	private int avgTime;
	private int lquTime;
	private int medTime;
	private int hquTime;
	public List<History> getRuns() {
		if (runs == null) runs = new ArrayList<History>();
		return runs;
	}
	public int getMinCost() {
		return minCost;
	}
	public int getMaxCost() {
		return maxCost;
	}
	public int getAvgCost() {
		return avgCost;
	}
	public int getLquCost() {
		return lquCost;
	}
	public int getMedCost() {
		return medCost;
	}
	public int getHquCost() {
		return hquCost;
	}
	public int getMinTime() {
		return minTime;
	}
	public int getMaxTime() {
		return maxTime;
	}
	public int getAvgTime() {
		return avgTime;
	}
	public int getLquTime() {
		return lquTime;
	}
	public int getMedTime() {
		return medTime;
	}
	public int getHquTime() {
		return hquTime;
	}
	
	// *** Constructors
	
	public Calculations(List<History> runs) {
		this.runs = runs;
		init();
	}
	
	// *** Methods
	
	public void init() {
		int pos = 0;
		List<Integer> costs = new LinkedList<Integer>();
		List<Integer> times = new LinkedList<Integer>();
		
		minCost = Integer.MAX_VALUE;
		maxCost = Integer.MIN_VALUE;
		avgCost = 0;
		lquCost = 0;
		medCost = 0;
		hquCost = 0;
		minTime = Integer.MAX_VALUE;
		maxTime = Integer.MIN_VALUE;
		avgTime = 0;
		lquTime = 0;
		medTime = 0;
		hquTime = 0;
		
		
		for (History history : getRuns()) {
			int totalUsageCost = history.getTotalUsageCost();
			if (maxCost <= totalUsageCost) maxCost = totalUsageCost;
			if (minCost >= totalUsageCost) minCost = totalUsageCost;
			avgCost += totalUsageCost;
			costs.add(totalUsageCost);
			
			int totalTime = history.getTimestamp().getValue();
			if (maxTime <= totalTime) maxTime = totalTime;
			if (minTime >= totalTime) minTime = totalTime;
			avgTime += totalTime;
			times.add(totalTime);
			
			pos++;
		}

		Collections.sort(costs);
		Collections.sort(times);
		
		if (getRuns().size() > 0) {
			avgCost /= getRuns().size();
			avgTime /= getRuns().size();
			lquCost = costs.get(costs.size() / 4);
			lquTime = times.get(times.size() / 4);
			medCost = costs.get(costs.size() / 2);
			medTime = times.get(times.size() / 2);
			hquCost = costs.get(costs.size() * 3 / 4);
			hquTime = times.get(times.size() * 3 / 4);
		} else {
			minCost = 0;
			maxCost = 0;
			avgCost = 0;
			lquCost = 0;
			medCost = 0;
			hquCost = 0;
			minTime = 0;
			maxTime = 0;
			avgTime = 0;
			lquTime = 0;
			medTime = 0;
			hquTime = 0;
		}
	}
	
	@Override
	public String toString() {
//		return 
//			"NC=" + minCost + ";" + 
//			"XC=" + maxCost + ";" + 
//			"GC=" + avgCost + ";" + 
//			"DC=" + medCost + ";" + 
//			"NT=" + minTime + ";" + 
//			"XT=" + maxTime + ";" + 
//			"GT=" + avgTime + ";" + 
//			"DT=" + medTime + ";";
		return
			"Min=" + minCost + "/" + minTime + ";" +
			"Max=" + maxCost + "/" + maxTime + ";" +
			"Avg=" + avgCost + "/" + avgTime + ";" +
			"LQu=" + lquCost + "/" + lquTime + ";" +
			"Med=" + medCost + "/" + medTime + ";" +
			"HQu=" + hquCost + "/" + hquTime + ";";
			
	}
}
